package cn.com.surker.production.controller;

import cn.com.surker.base.BaseEntity;
import cn.com.surker.base.pump.entity.CastMode;
import cn.com.surker.base.pump.entity.PumpNorm;
import cn.com.surker.base.pump.entity.PumpType;
import cn.com.surker.base.strength.entity.BaseStrength;
import cn.com.surker.cache.CacheManager;
import cn.com.surker.cache.MemoryCache;
import cn.com.surker.common.Code;
import cn.com.surker.enums.ICodeDescEnum;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.enums.base.PumpCostEnum;
import cn.com.surker.enums.production.indent.CreateTypeEnum;
import cn.com.surker.enums.production.indent.IsProEnum;
import cn.com.surker.enums.production.indent.ProTypeEnum;
import cn.com.surker.enums.production.indent.RoadTypeEnum;
import cn.com.surker.handler.DisCoordinator;
import cn.com.surker.oa.entity.OaProductionContract;
import cn.com.surker.production.entity.ProductionIndent;
import cn.com.surker.production.entity.ProductionIndentPump;
import cn.com.surker.production.entity.ProductionInvoice;
import cn.com.surker.production.entity.PumpDevice;
import cn.com.surker.production.entity.report.ProductionIndentPlan;
import cn.com.surker.production.entity.vo.ProductionIndentDisVo;
import cn.com.surker.production.entity.vo.ProductionIndentVo;
import cn.com.surker.sale.entity.SaleContract;
import cn.com.surker.sale.entity.SaleContractStrengthPrice;
import cn.com.surker.sale.service.SaleContractStrengthPriceBaseService;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.model.CacheUser;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.transaction.RollbackException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 生产任务单操作
 *
 * @author luotao
 * @date 2024/9/3
 */
@RestController
@RequestMapping("/pro/indent")
public class IndentController extends ProBaseController {

	private MemoryCache memoryCache = MemoryCache.getInstance();

	@Autowired
	private SaleContractStrengthPriceBaseService saleContractStrengthPriceBaseService;

	@RequestMapping(value = "/detail/{id}", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto detail(@PathVariable Long id) {
		if (id == null) {
			return RestResultDto.fail("请选择任务单");
		}
		ProductionIndent indent = indentService.queryFullById(erpDb, id);
		if (indent == null) {
			return RestResultDto.fail("未查询出任务单");
		}
		return RestResultDto.success(indent);
	}

	/**
	 * 查询任务单列表
	 *
	 * @param startDate
	 * @param endDate
	 * @param searchVal
	 * @param proType
	 * @return
	 */
	@RequestMapping(value = "/list", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto list(String startDate, String endDate, String searchVal, Integer proType) {
		List<Integer> proTypes = null;
		if (proType != null) {
			proTypes = new ArrayList<>();
			proTypes.add(proType);
		}
		List<ProductionIndentVo> indents = indentService.selectFullList(erpDb, startDate, endDate, searchVal, null, proTypes);
		return RestResultDto.success(indents);
	}

	/**
	 * 分页数据
	 *
	 * @return
	 */
	@RequestMapping(value = "/page", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto page(String startDate, String endDate, String searchVal, Integer proType, Integer pageIndex, Integer limit) {
		List<Integer> proTypes = null;
		if (proType != null) {
			proTypes = new ArrayList<>();
			proTypes.add(proType);
		}
		if (pageIndex == null) {
			pageIndex = 0;
		}
		if (limit == null) {
			limit = 50;
		}
		IPage<ProductionIndentVo> page = indentService.selectFullPage(erpDb, startDate, endDate, searchVal, null, proTypes, pageIndex, limit);
		return RestResultDto.success(page);
	}

	/**
	 * 分页数据,有别于page,如果该方法中的proType没有传入,则默认查询正供的和暂停的
	 *
	 * @return
	 */
	@RequestMapping(value = "/work/list", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto workList(Integer proType) {
		List<Integer> proTypes = new ArrayList<>();
		if (proType == null) {
			proTypes.add(ProTypeEnum.WORK.getCode());
			proTypes.add(ProTypeEnum.PAUSE_PRO.getCode());
		} else {
			proTypes.add(proType);
		}
		List<ProductionIndentDisVo> productionIndentReports = indentService.dispatchList(erpDb, proTypes);
		//	正供任务单列表
		ArrayList<Long> workIndentIdList = null;
		if (productionIndentReports != null) {
			workIndentIdList = productionIndentReports.stream().map(ProductionIndentDisVo::getId).collect(Collectors.toCollection(ArrayList::new));
		}
		memoryCache.set(DisCoordinator.workIndentKey, workIndentIdList);
		return RestResultDto.success(productionIndentReports);
	}

	/**
	 * 新增任务单
	 *
	 * @param conId             合同id
	 * @param strengthId        强度等级id
	 * @param planStere         计划方量
	 * @param castModeId       浇筑方式
	 * @param pumpDeviceIds      浇筑设备
	 * @param site              施工部位
	 * @param slumps            塌落度
	 * @param distance          运距
	 * @param address           工地地址
	 * @param linkMan           工地联系人
	 * @param linkPhone         工地联系电话
	 * @param dispatchStartTime 调度计划开盘时间
	 * @return
	 */
	@RequestMapping(value = "/add", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto add(Long conId, Long strengthId, Double planStere, Long castModeId, Long pumpTypeId, Long pumpNormId, Integer type, String site, String slumps, String slumpsSuffix,
							 String techId, String tech, @RequestParam(value = "pumpDeviceIds[]", required = false) Long[] pumpDeviceIds, Double distance, String address, String linkMan,
							 String linkPhone, String dispatchStartTime, String foreman, Integer roadType, Integer overLimit) {
		if (conId == null) {
			return RestResultDto.fail("未选择合同");
		}
		if (strengthId == null) {
			return RestResultDto.fail("未选择强度等级");
		}
		if (planStere == null) {
			return RestResultDto.fail("未输入计划方量");
		}
		if (planStere <= 0) {
			return RestResultDto.fail("请输入大于0的计划方量");
		}
		if (castModeId == null) {
			return RestResultDto.fail("未选择浇筑方式");
		}
		if (StringUtils.isBlank(site)) {
			return RestResultDto.fail("请输入施工部位");
		}
		// slumps = slumps + slumpsSuffix;
		if (StringUtils.isBlank(slumps)) {
			return RestResultDto.fail("请输入塌落度");
		}
		//	验证施工地址
		if (StringUtils.isBlank(site)) {
			return RestResultDto.fail("请输入施工部位");
		}
		//	验证开盘时间
		/*if (!StringUtils.validatorDate(builderStartTime, DateUtil.DATE_DETAIL_FORMATTER_SHORT)) {
			//	时间格式不对
			return RestResultDto.fail("工地开盘时间格式错误");
		}*/
		if (!StringUtils.validatorDate(dispatchStartTime, DateUtil.DATE_DETAIL_FORMATTER_SHORT)) {
			//	时间格式不对
			return RestResultDto.fail("计划开盘时间格式错误");
		}
		RestResultDto conValRes = validateConPro(conId, strengthId, planStere);
		if (RestResultDto.SUCCESS != conValRes.getCode()) {
			//	验证失败
			return conValRes;
		}
		ProTypeEnum typeEnum = ICodeDescEnum.getEnum(ProTypeEnum.class, type);
		if (typeEnum == null) {
			return RestResultDto.fail("任务单供应类型错误");
		}
		RoadTypeEnum roadTypeEnum = ICodeDescEnum.getEnum(RoadTypeEnum.class, roadType);
		if (roadTypeEnum == null) {
			return RestResultDto.fail("道路类型非法");
		}
		//	销售合同+
		SaleContract saleCon = (SaleContract) conValRes.getData();
		//	验证强度等级
		BaseStrength strength = strengthService.getById(strengthId);
		if (!BaseEntity.validateExist(strength)) {
			return RestResultDto.fail("强度等级(" + strengthId + ")非法");
		}
		//	验证浇筑方式
		CastMode castMode = castModeService.getById(castModeId);
		if (!BaseEntity.validateExist(castMode)) {
			return RestResultDto.fail("浇筑方式(" + castModeId + ")非法");
		}
		CacheUser user = getUser();
		//	是否需要设备
		Integer needDevice = castMode.getCost();
		List<ProductionIndentPump> indentPumpList = new ArrayList<>();
		;
		if (PumpCostEnum.COST.getCode().equals(needDevice)) {
			//	需要公司派遣泵送设备
			if (pumpDeviceIds == null || pumpDeviceIds.length < 1) {
				return RestResultDto.fail("请选择泵送设备");
			}
			if (pumpDeviceIds.length > 1) {
				return RestResultDto.fail("任务单只能选择一个泵送设备");
			}
			for (Long pumpDeviceId : pumpDeviceIds) {
				if (pumpDeviceId == null) {
					return RestResultDto.fail("泵送设备非法");
				}
				//	查询泵送设备是否是该站点合同所属的合同
				PumpDevice pumpDevice = pumpDeviceService.getById(pumpDeviceId);
				if (!BaseEntity.validateExist(pumpDevice)) {
					return RestResultDto.fail("泵送设备非法");
				}
				List<OaProductionContract> pumpConList = pumpConDeviceService.findDevConList(orgId, pumpDeviceId);
				if (pumpConList == null || pumpConList.isEmpty()) {
					// return RestResultDto.fail("该泵送设备在该站点下无合同,不允许使用");
				}
				//	添加关联关系
				ProductionIndentPump indentPump = new ProductionIndentPump(orgId, castModeId, pumpDeviceId, pumpDevice.getPumpTypeId(), pumpDevice.getPumpNormId());
				indentPump.setCreator(user.getName());
				indentPumpList.add(indentPump);
			}
		} else {
			//	不需要泵送设备,设置浇筑方式即可
			ProductionIndentPump indentPump = new ProductionIndentPump(orgId, castModeId, null, null, null);
			indentPump.setCreator(user.getName());
			indentPumpList.add(indentPump);
		}
		//	泵送类型
		PumpType pumpType = null;
		//	泵送规格
		PumpNorm pumpNorm = null;
		if (pumpTypeId != null) {
			pumpType = pumpTypeService.getById(pumpTypeId);
			if (!BaseEntity.validateExist(pumpType)) {
				return RestResultDto.fail("泵送类型非法");
			}
		}
		if (pumpNormId != null) {
			pumpNorm = pumpNormService.getById(pumpNormId);
			if (!BaseEntity.validateExist(pumpNorm)) {
				return RestResultDto.fail("泵送规格非法");
			}
		}

		//	合同属性
		Integer quality = saleCon.getQuality();
		//	是否需要验证合同中是否存在强度等级和泵送规格
		//	查询合同中的强度等级
		List<BaseStrength> conStrengthList = strengthService.findBySaleCon(conId);
		if (conStrengthList == null || conStrengthList.isEmpty()) {
			return RestResultDto.fail("该项目不是零星合同,只能生产合同中存在的标号(合同无标号)");
		}
		if (!conStrengthList.contains(strength)) {
			return RestResultDto.fail("该项目不是零星合同,只能生产合同中存在的标号(该合同中不存在[" + strength.getStrength() + "])");
		}
		//	查询合同中的泵送类型
		if (PUMP_ENABLE_QUALITY && pumpType != null && PumpCostEnum.COST.getCode().equals(pumpType.getCost())) {
			//	需要收费
			List<PumpType> salePumpTypeList = pumpTypeService.findBySaleCon(conId);
			if (salePumpTypeList == null || salePumpTypeList.isEmpty()) {
				return RestResultDto.fail("该项目不是零星合同,只能使用合同中存在的泵送类型(合同无泵送类型)");
			}
			//	存在泵送类型
			boolean hasPt = false;
			for (PumpType stype : salePumpTypeList) {
				if (stype.getId().equals(pumpTypeId)) {
					hasPt = true;
				}
			}
			if (!hasPt) {
				//	不存在
				return RestResultDto.fail("该项目不是零星合同,只能使用合同中存在的泵送类型(合同无泵送类型:" + pumpTypeId + ")");
			}
		}
		//	查询合同中的和泵送规格
		if (PUMP_ENABLE_QUALITY && pumpNorm != null && PumpCostEnum.COST.getCode().equals(pumpNorm.getCost())) {
			List<PumpNorm> salePumpNormList = pumpNormService.findBySaleCon(conId);
			if (salePumpNormList == null || salePumpNormList.isEmpty()) {
				return RestResultDto.fail("该项目不是零星合同,只能使用合同中存在的泵送规格(合同无泵送规格)");
			}
			//	存在泵送类型
			boolean hasPn = false;
			for (PumpNorm sNorm : salePumpNormList) {
				if (sNorm.getId().equals(pumpNormId)) {
					hasPn = true;
				}
			}
			if (!hasPn) {
				//	不存在
				return RestResultDto.fail("该项目不是零星合同,只能使用合同中存在的泵送规格(合同无泵送规格:" + pumpNormId + ")");
			}
		}
		//	调用接口处理数据
		if (techId != null) {
			//	获取强度等级的基础标号
			BaseStrength baseStrength = strengthService.getById(strengthId);
			if (baseStrength != null){
				Long levelId = baseStrength.getLevelId();
				if (levelId != null){
					RestResultDto restResultDto = saleContractStrengthPriceBaseService.generatePrice(conId, levelId, techId);
					if (restResultDto.getCode() != Code.SUCCESS.getCode()) {
						//	组合失败
						return restResultDto;
					}
					SaleContractStrengthPrice strengthPrice = (SaleContractStrengthPrice) restResultDto.getData();
					strengthId = strengthPrice.getStrengthId();
				}
			}
		}
		//	存储任务单数据
		ProductionIndent proIndent = new ProductionIndent();
		proIndent.setOrgId(orgId);
		proIndent.setConId(conId);
		proIndent.setSite(site);
		proIndent.setStrengthId(strengthId);
		proIndent.setTechId(techId);
		proIndent.setTech(tech);
		proIndent.setSlumps(slumps);
		proIndent.setDistance(distance);
		proIndent.setAddress(address);
		proIndent.setCastModeId(castModeId);
		// proIndent.setPumpDeviceId(pumpDeviceId);
		proIndent.setPumpTypeId(pumpTypeId);
		proIndent.setPumpNormId(pumpNormId);
		proIndent.setLinkMan(linkMan);
		proIndent.setLinkPhone(linkPhone);
		proIndent.setPlanStere(planStere);
		proIndent.setType(type);
		proIndent.setIsPro(IsProEnum.WAIT.getCode());
		proIndent.setCreateType(CreateTypeEnum.HAND.getCode());
		proIndent.setCreator(user.getName());
		proIndent.setCreateTime(new Date());
		proIndent.setForeman(foreman);
		// proIndent.setBuilderStartTime(DateUtil.convertDate(builderStartTime, DateUtil.DATE_DETAIL_FORMATTER_SHORT));
		proIndent.setDispatchStartTime(DateUtil.convertDate(dispatchStartTime, DateUtil.DATE_DETAIL_FORMATTER_SHORT));
		proIndent.setRoadType(roadType);
		proIndent.setOverLimit(overLimit);
		// String indentCode = ProductionIndent.initCode(orgCode);
		// proIndent.setCode(indentCode);
		proIndent.initCode(orgCode);
		//	插入任务单
		indentService.save(proIndent);
		List<Long> indentIds = new ArrayList<>();
		indentIds.add(proIndent.getId());
		RestResultDto restResultDto = updateIndentType(indentIds, type);
		if (!Code.SUCCESS.getCode().equals(restResultDto.getCode())) {
			//	不是成功状态
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return restResultDto;
		}
		//	插入关联泵送设备
		if (indentPumpList != null && indentPumpList.size() > 0) {
			Long indentId = proIndent.getId();
			for (ProductionIndentPump indentPump : indentPumpList) {
				indentPump.setIndentId(indentId);
			}
			indentPumpService.saveBatch(indentPumpList);
		}
		return RestResultDto.success();
	}

	/**
	 * 更新任务单基本信息
	 *
	 * @param planStere
	 * @param castModeId
	 * @param pumpDeviceIds
	 * @param pumpTypeId
	 * @param pumpNormId
	 * @param type
	 * @param slumps
	 * @param distance
	 * @param address
	 * @param linkMan
	 * @param linkPhone
	 * @param dispatchStartTime
	 * @return
	 */
	@RequestMapping(value = "/update/{indentId}", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto updateInfo(@PathVariable Long indentId, Double planStere, Long castModeId, @RequestParam(value = "pumpDeviceIds[]", required = false) Long[] pumpDeviceIds, Long pumpTypeId, Long pumpNormId,
									Integer type, String techId, String tech, String slumps, Double distance, String address, String linkMan, String linkPhone, String dispatchStartTime,
									String foreman, Integer roadType, Integer overLimit) {
		if (indentId == null) {
			return RestResultDto.fail("请选择任务单");
		}
		if (planStere == null) {
			return RestResultDto.fail("未输入计划方量");
		}
		if (planStere <= 0) {
			return RestResultDto.fail("请输入大于0的计划方量");
		}
		ProductionIndent oldIndent = indentService.getById(indentId);
		if (!BaseEntity.validateExist(oldIndent)) {
			//	没有旧数据
			return RestResultDto.fail("该任务单不存在或者已经被删除");
		}
		if (castModeId == null) {
			return RestResultDto.fail("未选择浇筑方式");
		}
		//	验证浇筑方式
		CastMode castMode = castModeService.getById(castModeId);
		if (castMode == null || !StateEnum.ENABLED.getCode().equals(castMode.getStatus())) {
			return RestResultDto.fail("浇筑方式(" + castModeId + ")非法");
		}
		Integer needDevice = castMode.getCost();
		// List<ProductionIndentPump> newIndentPumpList = new ArrayList<>();
		ProductionIndentPump newIndentPump = new ProductionIndentPump();
		if (PumpCostEnum.COST.getCode().equals(needDevice)) {
			//	需要公司派遣泵送设备
			if (pumpDeviceIds == null || pumpDeviceIds.length < 1) {
				return RestResultDto.fail("请选择泵送设备");
			}
			for (Long pumpDeviceId : pumpDeviceIds) {
				if (pumpDeviceId == null) {
					return RestResultDto.fail("泵送设备非法");
				}
				//	查询泵送设备是否是该站点合同所属的合同
				PumpDevice pumpDevice = pumpDeviceService.getById(pumpDeviceId);
				if (!BaseEntity.validateExist(pumpDevice)) {
					return RestResultDto.fail("泵送设备非法");
				}
				List<OaProductionContract> pumpConList = pumpConDeviceService.findDevConList(orgId, pumpDeviceId);
				if (pumpConList == null || pumpConList.isEmpty()) {
					// return RestResultDto.fail("该泵送设备在该站点下无合同,不允许使用");
				}
				//	添加关联关系
				ProductionIndentPump indentPump = new ProductionIndentPump(orgId, castModeId, pumpDeviceId, pumpDevice.getPumpTypeId(), pumpDevice.getPumpNormId());
				indentPump.setIndentId(indentId);
				// newIndentPumpList.add(indentPump);
				newIndentPump = indentPump;
				//	只取第一个
				break;
			}
		} else {
			//	不需要泵送设备,设置浇筑方式即可
			ProductionIndentPump indentPump = new ProductionIndentPump(orgId, castModeId, null, null, null);
			indentPump.setIndentId(indentId);
			// newIndentPumpList.add(indentPump);
			newIndentPump = indentPump;
		}
		if (!StringUtils.validatorDate(dispatchStartTime, DateUtil.DATE_DETAIL_FORMATTER_SHORT)) {
			//	时间格式不对
			return RestResultDto.fail("计划开盘时间格式错误");
		}
		//	调用接口处理数据
		if (techId != null) {
			String oldIndentTechId = oldIndent.getTechId();
			if (!techId.equals(oldIndentTechId)){
				//	标号存在变动
				Long conId = oldIndent.getConId();
				Long strengthId = oldIndent.getStrengthId();
				//	获取强度等级的基础标号
				BaseStrength baseStrength = strengthService.getById(strengthId);
				if (baseStrength != null){
					Long levelId = baseStrength.getLevelId();
					if (levelId != null){
						RestResultDto restResultDto = saleContractStrengthPriceBaseService.generatePrice(conId, levelId, techId);
						if (restResultDto.getCode() != Code.SUCCESS.getCode()) {
							//	组合失败
							return restResultDto;
						}
						SaleContractStrengthPrice strengthPrice = (SaleContractStrengthPrice) restResultDto.getData();
						strengthId = strengthPrice.getStrengthId();
						oldIndent.setStrengthId(strengthId);
						oldIndent.setTechId(techId);
						oldIndent.setTech(tech);
					}
				}
			}
		}
		CacheUser user = getUser();
		oldIndent.setSlumps(slumps);
		oldIndent.setDistance(distance);
		oldIndent.setAddress(address);
		oldIndent.setCastModeId(castModeId);
		oldIndent.setPumpTypeId(pumpTypeId);
		oldIndent.setPumpNormId(pumpNormId);
		oldIndent.setLinkMan(linkMan);
		oldIndent.setLinkPhone(linkPhone);
		oldIndent.setPlanStere(planStere);
		oldIndent.setForeman(foreman);
		//	oldIndent.setType(type);
		oldIndent.setUpdator(user.getName());
		// oldIndent.setBuilderStartTime(DateUtil.convertDate(builderStartTime, DateUtil.DATE_DETAIL_FORMATTER_SHORT));
		oldIndent.setDispatchStartTime(DateUtil.convertDate(dispatchStartTime, DateUtil.DATE_DETAIL_FORMATTER_SHORT));
		oldIndent.setRoadType(roadType);
		oldIndent.setOverLimit(overLimit);
		//	插入任务单
		indentService.updateById(oldIndent);
		//	更新任务单状态
		List<Long> ids = new ArrayList<>();
		ids.add(indentId);
		Integer oldIndentType = oldIndent.getType();
		if (!oldIndentType.equals(type)) {
			//	更改了任务单状态
			RestResultDto utRes = updateIndentType(ids, type);
			if (!Code.SUCCESS.getCode().equals(utRes.getCode())) {
				//	更新任务单状态失败,会滚数据
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return utRes;
			}
		}
		//	查询旧的泵送设备
		List<ProductionIndentPump> oldIndentPumps = indentPumpService.findByIndentId(erpDb, indentId);
		//	查询旧的发货单数据
		List<ProductionInvoice> invoiceList = invoiceService.defaultPumpList(indentId);
		if (oldIndentPumps != null && oldIndentPumps.size() > 0) {
			//	存在旧设备,删除新数据中不存在的旧数据,添加新数据中存在,旧数据中不存在的数据
			// List<ProductionIndentPump> addIndentPumps = new ArrayList<>();
			List<Long> delIndentPumpIds = new ArrayList<>();
			for (ProductionIndentPump item : oldIndentPumps) {
				/*if (!newIndentPumpList.contains(item)) {
					//	旧数据不在新数据中,需要删除
					delIndentPumpIds.add(item.getId());
				}*/
				Integer isDefault = item.getIsDefault();
				if (StateEnum.DISABLED.getCode().equals(isDefault)) {
					//	默认数据不删除
					continue;
				}
				if (!newIndentPump.equals(item)) {
					delIndentPumpIds.add(item.getId());
				}
			}
			/*for (ProductionIndentPump item : newIndentPumpList) {
				if (!oldIndentPumps.contains(item)) {
					//	新数据不在旧数据中,需要新增
					addIndentPumps.add(item);
				}
			}*/
			if (!oldIndentPumps.contains(newIndentPump)) {
				//	新数据不在旧数据中,需要新增
				indentPumpService.save(newIndentPump);
			}
			// indentPumpService.saveBatch(addIndentPumps);
			indentPumpService.deletePumps(delIndentPumpIds);
		} else {
			//	不存在旧设备,直接新增
			// indentPumpService.saveBatch(newIndentPumpList);
			indentPumpService.save(newIndentPump);
		}
		//	查询浇筑方式是默认的发货单
		Long linkPumpId = newIndentPump.getId();
		//	变更了泵送设备
		if (linkPumpId != null && invoiceList != null && invoiceList.size() > 0) {
			List<Long> invIdList = invoiceList.stream().map(ProductionInvoice::getId).collect(Collectors.toList());
			UpdateWrapper<ProductionInvoice> uw = new UpdateWrapper<>();
			uw.in("id", invIdList);
			uw.set("link_pump_id", linkPumpId);
			boolean update = invoiceService.update(uw);

		}
		return RestResultDto.success();
	}


	/**
	 * 修改任务单的生产信息(转正供,或者供毕)
	 *
	 * @param indentIds 任务单id
	 * @param proType   生产状态
	 * @return
	 */
	@RequestMapping(value = "/update/pro", method = RequestMethod.PUT)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto updateIndentType(String indentIds, Integer proType) {
		if (StringUtils.isBlank(indentIds) || proType == null) {
			return RestResultDto.fail(Code.PARAM_EMPTY);
		}
		List<Long> ids = JSONArray.parseArray(indentIds, Long.class);
		ProTypeEnum typeEnum = ICodeDescEnum.getEnum(ProTypeEnum.class, proType);
		if (typeEnum == null) {
			return RestResultDto.fail("任务单生产类型错误(仅可选择待供,正供,供毕)");
		}
		RestResultDto res = updateIndentType(ids, proType);
		return res;
	}

	/**
	 * 删除任务单
	 *
	 * @param indentId
	 * @return
	 */
	@RequestMapping(value = "/delete/{indentId}", method = RequestMethod.DELETE)
	@ResponseBody
	@Transactional(rollbackFor = RollbackException.class, propagation = Propagation.REQUIRED)
	public RestResultDto delIndent(@PathVariable Long indentId) {
		//	查询任务单数据
		ProductionIndent proIndent = indentService.getById(indentId);
		if (!BaseEntity.validateExist(proIndent)) {
			return RestResultDto.fail("任务单不存在或者已删除");
		}
		//	任务单是否开盘
		Integer isPro = proIndent.getIsPro();
		if (IsProEnum.WORK.getCode().equals(isPro)) {
			//	生产了的任务单不允许删除
			return RestResultDto.fail("任务单已经生产,不允许删除");
		}
		//	删除数据
		int delete = indentService.delete(indentId);
		return RestResultDto.success();
	}

	/**
	 * 查询任务单下的泵送设备列表
	 *
	 * @param indentId
	 * @return
	 */
	@RequestMapping(value = "/pump-dev-list", method = RequestMethod.POST)
	@ResponseBody
	@Deprecated
	public RestResultDto pumpDeviceList(Long indentId) {
		if (indentId == null) {
			return RestResultDto.fail("请传入任务单");
		}
		List<PumpDevice> pumpDeviceList = pumpDeviceService.findByIndentId(orgId, indentId);
		return RestResultDto.success(pumpDeviceList);
	}

	/**
	 * 验证任务单格式是否可以修改
	 *
	 * @param indentIds 任务单列表
	 * @param type   任务单状态
	 * @return
	 */
	private RestResultDto updateIndentType(List<Long> indentIds, Integer type) {
		if (indentIds == null || type == null) {
			return RestResultDto.fail("任务单或者任务单类型为空");
		}
		if (ProTypeEnum.WORK.getCode().equals(type)) {
			//	如果是转正任务单,查询是否上传配合比
			int r = indentService.updateIndentPro(indentIds, type, null);
			return RestResultDto.success();
		} else if (ProTypeEnum.WAIT.getCode().equals(type)) {
			//	改为待供,验证是否有小票
			for (Long indentId : indentIds) {
				List<ProductionInvoice> invoiceList = invoiceService.findByIndent(erpDb, indentId);
				if (invoiceList != null && invoiceList.size() > 0) {
					//	查询该任务单
					ProductionIndent indent = indentService.getById(indentId);
					String code = indent.getCode();
					return RestResultDto.fail("任务单[" + code + "]下存在发货单,不允许转待供");
				}
				//	更新数据
				int r = indentService.updateIndentPro(indentIds, type, null);
				return RestResultDto.success();
			}
		} else if (ProTypeEnum.PAUSE_PRO.getCode().equals(type)) {
			//	查询任务单下的派单信息
			/*ThreadPoolExecutor commonThreadPool = ThreadPools.getCommonThreadPool();
			commonThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					List<ProductionIndentDispatch> list = indentDispatchService.findByIndentIds(indentIds);
					for (ProductionIndentDispatch dispatch : list) {
						// bcsStarter.startDelDis(dispatch.getId());
					}
				}
			});*/
			//	更新状态
			int r = indentService.updateIndentPro(indentIds, type, null);
			return RestResultDto.success();
		} else {
			//	其他的的则直接更新任务单状态
			int r = indentService.updateIndentPro(indentIds, type, null);
			return RestResultDto.success();
		}
		return RestResultDto.fail();
	}

	/**
	 * 查询任务单的累计车辆和车次
	 *
	 * @param indentId
	 * @return
	 */
	@RequestMapping(value = "/queryTotal", method = RequestMethod.POST)
	@ResponseBody
	public RestResultDto queryTotalStere(Long indentId) {
		if (indentId == null) {
			return RestResultDto.fail(Code.PARAM_EMPTY);
		}
		Map<String, Object> totalMap = invoiceService.queryTotalStere(erpDb, indentId);
		if (totalMap == null) {
			totalMap = new HashMap<>();
			totalMap.put("totalCar", 0);
			totalMap.put("totalStere", 0d);
		}
		//	查询车辆编号
		return RestResultDto.success(totalMap);
	}

	/**
	 * 导出生产计划
	 */
	@RequestMapping(value = "/export", method = RequestMethod.POST)
	@ResponseBody
	public void overviewStatExport(String startDate, String endDate, String searchVal, Integer proType, HttpServletResponse response) {
		if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
			//	没有筛选时间断
			return;
		}
		CacheUser user = getUser();
		List<Integer> proTypes = null;
		if (proType != null) {
			proTypes = new ArrayList<>();
			proTypes.add(proType);
		}
		List<ProductionIndentVo> indents = indentService.selectFullList(erpDb, startDate, endDate, searchVal, null, proTypes);
		if (indents == null || indents.isEmpty()) {
			return;
		}
		List<ProductionIndentPlan> planList = new ArrayList<>();
		for (int i = 0, s = indents.size(); i < s; i++) {
			ProductionIndentVo indentVo = indents.get(i);
			ProductionIndentPlan productionIndentPlan = new ProductionIndentPlan(indentVo);
			planList.add(productionIndentPlan);
		}
		XSSFWorkbook hw = new XSSFWorkbook();
		String sheetName = orgName + "生产计划(" + startDate + "~" + endDate + ")";
		try {
			hw = exportTotalReport(sheetName, "制表人" + user.getName() + ",导出时间:" + DateUtil.convertString(new Date()), planList, hw);
		} catch (Exception e) {
			e.printStackTrace();
		}
		OutputStream os = null;
		try {
			//响应到客户端
			this.setResponseHeader(response, sheetName + ".xlsx");
			os = response.getOutputStream();
			hw.write(os);
			os.flush();
			os.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
